package org.itboys.weixin;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.itboys.framework.spring.context.SpringContextHolder;
import org.itboys.fuzion.constant.FuzionConstants;
import org.itboys.fuzion.dto.FuzionMemberRedisDto;
import org.itboys.fuzion.entity.IncomeExpenditureRecords;
import org.itboys.fuzion.entity.ScoreLevel;
import org.itboys.fuzion.mysql.dao.FuziongMemberStatisticsMapper;
import org.itboys.fuzion.mysql.orm.FuziongMemberStatistics;
import org.itboys.fuzion.service.FuzionMemberService;
import org.itboys.fuzion.service.IncomeExpenditureRecordsService;
import org.itboys.fuzion.service.ScoreLevelService;
import org.itboys.weixin.constant.WeixinConstants;
import org.itboys.weixin.service.WeixinSendInfoService;
import org.itboys.weixin.tools.HttpHelper;
import org.itboys.weixin.tools.WeixinUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by huml on 2016/4/28.
 * 定时任务
 * 自动发放收益
 */
@Configuration
@EnableScheduling // 启用定时任务
public class SchedulingConfig {

    private static final Logger logger = LoggerFactory.getLogger(SchedulingConfig.class);

    private static ExecutorService fixedTimeThreadPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

    @Scheduled(cron = "59 59 23 * * ?") // 每天凌晨12(23:59:59)点执行一次
    public void scheduler() {
    	/*FuziongMemberStatisticsMapper fuziongMemberStatisticsMapper = SpringContextHolder.getBean("fuziongMemberStatisticsMapper");
        IncomeExpenditureRecordsService incomeExpenditureRecordsService = SpringContextHolder.getBean("incomeExpenditureRecordsService");
        ScoreLevelService scoreLevelService = SpringContextHolder.getBean("scoreLevelService");
        FuzionMemberService memberService = SpringContextHolder.getBean("fuzionMemberService");
        WeixinSendInfoService weixinSendInfoService = SpringContextHolder.getBean("weixinSendInfoService");
        //取出所有的等级
        List<ScoreLevel> levels = scoreLevelService.list(Maps.newHashMapWithExpectedSize(0));
        //取出所有的卖家
        List<FuziongMemberStatistics> sellers = fuziongMemberStatisticsMapper.getSellerStatistics();
        //遍历卖家
        for (FuziongMemberStatistics sellerStatistics : sellers) {
            try {
                signalSeller(fuziongMemberStatisticsMapper, incomeExpenditureRecordsService, levels, sellerStatistics, memberService, weixinSendInfoService);
            } catch (Exception e) {
            	e.printStackTrace();
            	logger.error("SchedulingConfig.scheduler error", e);
                continue;
            }
        }*/
    }

    /**
     * 单个卖家的处理逻辑  作为一个事物回滚
     * @param fuziongMemberStatisticsMapper
     * @param incomeExpenditureRecordsService
     * @param levels
     * @param sellerStatistics
     */
    @Transactional
    private void signalSeller(FuziongMemberStatisticsMapper fuziongMemberStatisticsMapper, IncomeExpenditureRecordsService incomeExpenditureRecordsService,
                              List<ScoreLevel> levels, FuziongMemberStatistics sellerStatistics, FuzionMemberService memberService, 
                              WeixinSendInfoService weixinSendInfoService) throws Exception{
        List<IncomeExpenditureRecords> list = Lists.newArrayList();//记录mongo的记录id,作为回滚用
        try {/*
            //计算卖家在不同等级的收益
            BigDecimal total = new BigDecimal(sellerStatistics.getNowTotalMoney());//总销售额
            logger.info("***********total*************"+total);
            BigDecimal totalAmount = new BigDecimal(0);
            List<String> openIds = Lists.newArrayList();//记录将要发送的对象openId
            String appId = null;
            String appSecret = null;
            //遍历等级
            for (ScoreLevel scoreLevel:levels) {
                //计算该等级下的奖金池金额  总销售额 * 5%
                BigDecimal amount = total.multiply(new BigDecimal(scoreLevel.getPercent())).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
                logger.info("*****************scoreLevel*************"+scoreLevel.getId()+"**********amount**********"+amount);
                totalAmount = totalAmount.add(amount);
                //卖家在该等级下的会员数
                List<FuziongMemberStatistics> qtMemberIdList = fuziongMemberStatisticsMapper.getMemberIdListByScoreId2(scoreLevel.getId(), sellerStatistics.getSellerId());
                int qtMemberNum = qtMemberIdList.size();
                
                //这里后台控制每日分红人数
        		if(scoreLevel.getPeopleNum() != null && scoreLevel.getPeopleNum() >= 0){
        			qtMemberNum = scoreLevel.getPeopleNum();
        		}
        		
                if(qtMemberNum > 0){
                    BigDecimal getAmount = amount.divide(new BigDecimal(qtMemberNum),2, BigDecimal.ROUND_HALF_UP);
                    logger.info("*****************scoreLevel*************"+scoreLevel.getId()+"**********getAmount**********"+getAmount);
                    for (FuziongMemberStatistics memberStatistics : qtMemberIdList) {
                        //会员收益增加
                        memberStatistics.setStaticIncome(memberStatistics.getStaticIncome() + getAmount.intValue());
                        memberStatistics.setNowTotalMoney(memberStatistics.getNowTotalMoney() + getAmount.intValue());
                        memberStatistics.setTotalMoney(memberStatistics.getTotalMoney() + getAmount.intValue());
                        logger.info("**********会员分红记录1************"+memberStatistics.toString());
//                      fuziongMemberStatisticsMapper.update(memberStatistics);
                        
                        //推送信息
                        FuzionMemberRedisDto redis_fuzion_member = memberService.getFuzionMemberRedisDto(memberStatistics.getMemberId());
    					if(redis_fuzion_member != null && redis_fuzion_member.getOpenId() != null){

                            WeixinSendInfo wsss = weixinSendInfoService.getByKey("day_red_package");
    						openIds.add(redis_fuzion_member.getOpenId());//把将要推送的对象openId放入集合
                            if(StringUtils.isNotBlank(appId)){
    							appId = redis_fuzion_member.getAppId();
    						}
    						if(StringUtils.isNotBlank(appSecret)){
    							appSecret = redis_fuzion_member.getAppSecret();
    						}
    						WeixinSendInfo wsss = weixinSendInfoService.getByKey("day_red_package");
        					String messagess = wsss.getValue().replace("{money}", "" + new BigDecimal(getAmount.intValue()).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP));
        					WeixinSendInfoThread.sendMessageSleep(redis_fuzion_member.getAppId(), redis_fuzion_member.getAppSecret(),
        							redis_fuzion_member.getOpenId(), messagess, 60000);//扔给线程池  1分钟后  再执行  如果执行过于频繁  微信会屏蔽推送
    					}
                        
//                        logger.info("**********会员分红记录2************"+memberStatistics.toString());
                        //生成明细记录
                        IncomeExpenditureRecords records = new IncomeExpenditureRecords();
                        records.setMemberId(memberStatistics.getMemberId());
                        records.setType(FuzionConstants.TYPE_ONE);
                        records.setMoney(getAmount.intValue());
                        records.setObjType(FuzionConstants.IncomeExpenditure.SELLER);
                        records.setObjId(String.valueOf(memberStatistics.getSellerId()));
//                        incomeExpenditureRecordsService.insert(records);
                        list.add(records);
                    }
                    //批量修改
                    fuziongMemberStatisticsMapper.batchUpdate(qtMemberIdList);
                    //批量插入
                    incomeExpenditureRecordsService.batchSave(list);
                }
            }
            //操作卖家的账户  nowTotalMoney归零  score加上拿出去分红之后剩余的钱
            sellerStatistics.setNowTotalMoney(0);
            totalAmount = total.subtract(totalAmount);
            logger.info("**********会员分红记录0************"+sellerStatistics.toString());
            sellerStatistics.setScore(sellerStatistics.getScore() == null ? totalAmount.intValue() : totalAmount.add(new BigDecimal(sellerStatistics.getScore())).intValue());
            logger.info("**********会员分红记录1************"+sellerStatistics.toString());
            fuziongMemberStatisticsMapper.update(sellerStatistics);
            logger.info("**********会员分红记录2************"+sellerStatistics.toString());
            //生成明细记录
            IncomeExpenditureRecords records = new IncomeExpenditureRecords();
            records.setMemberId(sellerStatistics.getSellerId());
            records.setType(FuzionConstants.TYPE_TWO);
            records.setMoney(-totalAmount.intValue());
            records.setObjType(FuzionConstants.IncomeExpenditure.SELLER);
            records.setObjId(String.valueOf(sellerStatistics.getSellerId()));
            incomeExpenditureRecordsService.insert(records);
//            recordIds.add(records.getId());
            list.add(records);

            //扔到线程中发送
            if(openIds != null && StringUtils.isNotBlank(appId) && StringUtils.isNotBlank(appSecret)){
//                saveSendGiveMoneyRecord(openIds, appId, appSecret);
            }
            Thread.sleep(60000);//睡一钟
        */} catch (Exception e) {
            if(!list.isEmpty()){
                List<Long> recordIds = Lists.newArrayListWithExpectedSize(list.size());
                for (IncomeExpenditureRecords records :
                        list) {
                    recordIds.add(records.getId());
                }
                Map<String, Object> param = Maps.newHashMapWithExpectedSize(1);
                param.put("id in", recordIds);
                incomeExpenditureRecordsService.delete(param);
            }
            throw new RuntimeException(e);
        }
    }

    /**
     * 开一个线程 将要发送的信息 放入表中
     */
    public static void saveSendGiveMoneyRecord(List<String> openIds, String appId, String appSecret) throws Exception{
        fixedTimeThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    //批量推送信息 这里就写死了
                    if(openIds.size() > 0){
                        Map<String,Object> param1 = Maps.newHashMapWithExpectedSize(3);
                        param1.put("msgtype","text");
                        Map<String,Object> text = Maps.newHashMapWithExpectedSize(1);
                        text.put("content","亲爱的小主，今日的英雄积分已经到位啦,请笑纳");
                        param1.put("touser",openIds);
                        param1.put("text",text);
                        logger.info("定时任务结束，批量推送信息："+JSON.toJSONString(param1));

                        if(StringUtils.isNotBlank(appId) && StringUtils.isNotBlank(appSecret)){
                            String token = WeixinUtils.getAccessToken(appId, appSecret);
                            String rsult = HttpHelper.doPost(WeixinConstants.URL.BATCH_SEND_MESSAGE+token, param1);
                            logger.info("批量推送信息结束，返回结果："+rsult);
                        }
                    }
                } catch (Exception e) {

                }

            }
        });
    }

}
